#include "stdafx.h"

#include <windows.h>
#include "renderer/renderer.h"
#include "physics/physics.h"
#include "threadpool.h"
#include "random.h"

#include "shapes.h"

#include "debug/timer.h"
#include "debug/print.h"
#include "renderer/renderer_exception.h"

#include "file/file_manager.h"
#include "texture/texture_manager.h"
#include "input/input_manager.h"

#include "objects/entity.h"
#include "octree/octree_manager.h"

#include "client.h"

#include <memory.h>
#include <stdlib.h>

int WINAPI WinMain(HINSTANCE instance, HINSTANCE hPrevInst, PSTR lpCmd, int show)
{

	io::CFileManager * fm = io::CFileManager::create();
	CTextureManager * tm = CTextureManager::create();
	CInputManager * im = CInputManager::create();
	CEntityManager * em = CEntityManager::create();

	octree::COCTreeManager::init();
//	octree::COCTree & octree = octree::COCTreeManager::getRoot();

	CRenderer * renderer;
//	CPhysicEngine * physicEngine;
	try
	{
		renderer = CRenderer::create(instance);
		renderer->run();
/*
		physicEngine = CPhysicEngine::create();
		physicEngine->run();
*/
	}
	catch (CRendererException & e)
	{
		MessageBoxA(NULL, e.getError(), NULL, MB_OK);
		return 0;
	}

	ShowCursor(FALSE);
	MSG msg;
	while (1)
	{
		while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			switch (msg.message & 0x0000FFFF)
			{
			case WM_MOUSEMOVE:
				{
					int x = msg.lParam & 0x0000FFFF;
					int y = (msg.lParam & 0xFFFF0000) >> 16;
					const SPoint & p = im->getMouse().getClientCenter();
					if (p.x == x && p.y == y)
						break;
					const SPoint & sp = im->getMouse().getScreenCenter();
					SetCursorPos(sp.x, sp.y);
					im->getMouse().mouseMove(x - p.x, y - p.y);
				}
				break;
			case WM_KEYDOWN:
				switch (msg.wParam)
				{
				case VK_F1:
					demo_toggle_entities();
					break;
				case VK_F2:
					demo_toggle_collisions();
					break;
				case VK_F3:
					demo_toggle_octree();
					break;
				case VK_F4:
					demo_toggle_rotation();
					break;
				}
				break;
			default:
				break;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
//			renderer->notifyStop();
	}
	return (int)msg.wParam;
}